package net.vipmro.search.importer.common;

import com.sunny.redis.CacheTime;
import com.sunny.redis.JedisHandler;
import net.vipmro.search.dto.constant.BusinessCacheKey;
import net.vipmro.search.dto.entity.Brand;
import net.vipmro.search.dto.entity.Category;
import net.vipmro.search.dto.entity.GoodsAttr;
import net.vipmro.search.dto.entity.SellerGoodsInfo;
import net.vipmro.search.importer.dao.BrandDAO;
import net.vipmro.search.importer.dao.CategoryDAO;
import net.vipmro.search.importer.dao.GoodsAttrDAO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * service基类
 * @author fengxiangyang
 * @date 2018/12/5
 */
public class BaseService {
    private static final Logger logger = LoggerFactory.getLogger(BaseService.class);

    @Autowired
    protected JedisHandler jedisHandler;
    @Resource
    private BrandDAO brandDAO;
    @Resource
    private CategoryDAO categoryDAO;
    @Resource
    private GoodsAttrDAO goodsAttrDAO;

    /**
     * bean对象转map，并去掉id和null值
     *
     * @param bean
     * @return
     */
    protected static Map<String, Object> convertBeanToMap(Object bean) {
        Class type = bean.getClass();
        Map<String, Object> returnMap = new HashMap<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(type);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < propertyDescriptors.length; i++) {
                PropertyDescriptor descriptor = propertyDescriptors[i];
                String propertyName = descriptor.getName();
                if (!propertyName.equals("id") && !propertyName.equals("class")) {
                    Method readMethod = descriptor.getReadMethod();
                    Object result = readMethod.invoke(bean, new Object[0]);
                    if (result != null) {
                        returnMap.put(propertyName, result);
                    }
                }
            }
        } catch (Exception e) {
            logger.info("bean转化为map失败:ex={},bean={}", e, bean);
        }
        returnMap.remove("id");
        return returnMap;
    }

    /**
     * 清除品牌缓存
     */
    protected void clearCacheBrand() {
        jedisHandler.del(BusinessCacheKey.BRAND.key());
    }

    /**
     * 获取品牌信息
     *
     * @return
     */
    protected Map<String, Set<String>> getBrandNames() {
        return jedisHandler.cache(BusinessCacheKey.BRAND.key(), () -> {
            final List<Brand> list = brandDAO.findAll();
            Map<String, Set<String>> map = new HashMap<>();
            for (Brand brand : list) {
                map.put(brand.getId().toString(), getBrandSet(brand));
            }
            return map;
        }, CacheTime.DAY_1);
    }

    private Set<String> getBrandSet(Brand entity) {
        String nameCN = entity.getNameCn();
        String nameEN = entity.getNameEn();
        Set<String> set = new HashSet<>();
        if (StringUtils.isNotEmpty(nameCN)) {
            set.add(nameCN);
        }
        if (StringUtils.isNotEmpty(nameEN)) {
            set.add(nameEN);
        }
        return set;
    }

    /**
     * 清除类别缓存
     */
    protected void clearCacheCategory() {
        jedisHandler.del(BusinessCacheKey.CATEGORY.key());
    }

    /**
     * 获取类别
     *
     * @return
     */
    protected Map<String, Set<String>> getCategoryNames() {
        return jedisHandler.cache(BusinessCacheKey.CATEGORY.key(), () -> {
            final List<Category> list = categoryDAO.findAll();
            Map<String, Set<String>> map = new HashMap<>();
            for (Category category : list) {
                if (category.getIsLeaf() == 1) {
                    final Set<String> cateNameSet = getCateNameSet(category, list);
                    map.put(category.getCateNo(), cateNameSet);
                }
            }
            return map;
        }, CacheTime.DAY_1);
    }

    private static Set<String> getCateNameSet(Category entity, List<Category> list) {
        Set<String> set = new HashSet<>();
        set.add(entity.getName());
        Integer parentId = entity.getParentId();
        while (parentId != 0) {
            boolean breakFlag = true;
            for (Category category : list) {
                if (parentId.intValue() == category.getId()) {
                    set.add(category.getName());
                    parentId = category.getParentId();
                    breakFlag = false;
                    break;
                }
            }
            if (breakFlag) {
                break;
            }
        }
        return set;
    }

    /**
     * 清除商品属性缓存
     */
    protected void clearCacheGoodsAttr(String goodsId) {
        jedisHandler.del(BusinessCacheKey.GOODS_ATTR.key(goodsId));
    }

    /**
     * 获取商品属性信息
     *
     * @param goodsId
     * @return
     */
    protected List<GoodsAttr> getGoodsAttrs(Long goodsId) {
        return jedisHandler.cache(BusinessCacheKey.GOODS_ATTR.key(goodsId), () -> goodsAttrDAO.findByGoodsId(goodsId), CacheTime.DAY_1);
    }

    /**
     * 商品信息转换并添加品牌和分类信息
     * @param goodsInfo
     * @return
     */
    protected Map<String, Object> getSellerGoodsInfoMap(SellerGoodsInfo goodsInfo){
        final Map<String, Set<String>> brandNames = getBrandNames();
        final Map<String, Set<String>> categoryNames = getCategoryNames();
        final Map<String, Object> map = convertBeanToMap(goodsInfo);

        if (null != goodsInfo.getBrandId()) {
            map.put("brandNames", brandNames.get(goodsInfo.getBrandId().toString()));
        }
        if (null != goodsInfo.getCategoryNo()) {
            map.put("categoryNames", categoryNames.get(goodsInfo.getCategoryNo()));
        }
        return map;
    }

    /**
     * 商品属性信息
     * @param set
     * @return
     */
    protected Map<Long, List<GoodsAttr>> getGoodsAttrMap(Set<String> set){
        final String goodsIds = set.stream().collect(Collectors.joining(","));
        final List<GoodsAttr> goodsAttrs = goodsAttrDAO.findByGoodsIds(goodsIds);
        return goodsAttrs.stream().collect(Collectors.groupingBy(GoodsAttr::getGoodsId));
    }

}